/*
 * DatabaseSubsystem.h
 *
 *  Created on: Apr 26, 2017
 *      Author: zhangjf
 */

#ifndef SRC_DATABASESUBSYSTEM_DATABASESUBSYSTEM_H_
#define SRC_DATABASESUBSYSTEM_DATABASESUBSYSTEM_H_

#include <vector>
#include <Poco/JSON/Object.h>
#include <Poco/JSON/Array.h>
#include <Poco/Logger.h>
#include <Poco/AutoPtr.h>
#include <Poco/Data/SessionPool.h>
#include <Poco/Util/Subsystem.h>

#include "NCSSubsystem.h"

using namespace std;
using namespace Poco;
using namespace Poco::Util;
using namespace Poco::Data;
using namespace Poco::JSON;
using namespace util;

namespace database
{

class DatabaseSubsystem: public NCSSubsystem
{
public:
	DatabaseSubsystem();
	virtual ~DatabaseSubsystem();

	const char* name() const { return _name.c_str(); }
	static DatabaseSubsystem& instance() { return *_pInstance; }

	//database Interface
	bool getAppCountWithCellType(std::string& cellType, UInt32& counter);
	bool isRegisterCellType(std::string& cellType);
	bool isAppNameExist(std::string& appName);

	bool registerCellType(std::string& cellType, string& zipFile, Object::Ptr& joCellInfo);

	bool queryCellID(std::string& cellType, UInt32& cellID);
	bool queryCellIDWithAppName(std::string& cellType, UInt32& cellID);
	bool queryAppID(std::string& appName, UInt32& appID);

	bool addApp(std::string& cellType, std::string& appName, UInt32& appID);

	bool getFreeAppName(std::string& cellType, std::string& appName);
	bool getFreeAppNames(std::string& cellType, std::vector<std::string>& vecAppNames, UInt32 num);

	bool getCellTypeList(std::vector<std::string>& vecCellType);
	bool getAppList(std::vector<std::string>& vecApp);
	bool getAppProperties(std::string& strAppName, JSON::Array& joProps, std::string& strError);

protected:
	void initialize(Application& self);
	void uninitialize();

private:
	static const std::string _name;
	static const std::string _strDBDir;
	static const std::string _strDBFileName;
	static const std::string _strDBDirBak;
	static DatabaseSubsystem* _pInstance;
	static const std::vector<string> _vecKnownCellFileType;

	AutoPtr<SessionPool> _sessionPool;

	bool registerCell(std::string& cellType, Object::Ptr& joCellInfo, UInt32& cellID);
	bool registerCellInfo(std::string& cellType, Object::Ptr& joCellInfo, UInt32& cellID);
	bool registerCellFiles(std::string& cellType, string& zipFile, Object::Ptr& joCellInfo);
	bool importCellProperties(std::string& cellType, Object::Ptr& joCellProperties);

	bool makeCellPropTableName(std::string& cellType, std::string& strTableName);
	bool makeCellPropTableNameWithAppName(std::string& appName, std::string& strTableName);
	bool makeAppPropTableName(std::string& appName, std::string& strTableName);

	std::string makeTableNameWithID(const std::string& prefix, UInt32 id);

	bool checkAppName(std::string& strAppName);
};

} /* namespace database */

#endif /* SRC_DATABASESUBSYSTEM_DATABASESUBSYSTEM_H_ */
